package com.yxhl.zoume.core.busticket.ui.fragment;


import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.yxhl.protobuf.BizOrder;
import com.yxhl.protobuf.BizOrderRequest;
import com.yxhl.protobuf.Contract;
import com.yxhl.protobuf.ContractType;
import com.yxhl.protobuf.GenderType;
import com.yxhl.protobuf.IdType;
import com.yxhl.protobuf.OneBusEntry;
import com.yxhl.protobuf.OneYxBusInfoRequest;
import com.yxhl.protobuf.OrderBizType;
import com.yxhl.protobuf.OrderSrcType;
import com.yxhl.protobuf.ScheduleType;
import com.yxhl.zoume.R;
import com.yxhl.zoume.common.presenter.PerfectCouponPresenter;
import com.yxhl.zoume.common.ui.fragment.BaseFragment;
import com.yxhl.zoume.common.ui.view.PerfectCouponView;
import com.yxhl.zoume.core.busticket.presenter.BusTicketOrderPresenter;
import com.yxhl.zoume.core.busticket.ui.activity.BusTicketOrderActivity;
import com.yxhl.zoume.core.busticket.view.BusTicketOrderView;
import com.yxhl.zoume.core.coupon.model.CouponSelectEvent;
import com.yxhl.zoume.core.coupon.model.CouponSelectModel;
import com.yxhl.zoume.core.func.passenger.event.DeletePsgerEvent;
import com.yxhl.zoume.core.func.passenger.event.RenderSelectedPsgersEvent;
import com.yxhl.zoume.core.func.passenger.event.RenderSelectedTakerEvent;
import com.yxhl.zoume.core.func.passenger.ui.MultipleSelectType;
import com.yxhl.zoume.core.func.passenger.ui.PsgerItemType;
import com.yxhl.zoume.core.func.passenger.ui.SelectPsgersAdapter;
import com.yxhl.zoume.data.http.model.busticket.ZMBusTicketOrder;
import com.yxhl.zoume.data.http.model.coupon.CouponInfo;
import com.yxhl.zoume.data.http.model.passenger.ZMPassenger;
import com.yxhl.zoume.di.component.busticket.BusServiceComponent;
import com.yxhl.zoume.utils.CollectionUtils;
import com.yxhl.zoume.utils.DensityUtils;
import com.yxhl.zoume.utils.IDNoUtils;
import com.yxhl.zoume.utils.LOG;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import rx.functions.Action1;

/**
 * 巴士车票订单
 * by Xboy
 */
public class BusTicketOrderFragment extends BaseFragment implements BusTicketOrderView, PerfectCouponView {

    public static final String TAG = "BusTicketOrderFrag";

    private static final String KEY_TICKET_DETAIL_PARAM = "TICKET_DETAIL_PARAM";
    private static final String KEY_TICKET_SCHEDULE_TYPE = "TICKET_DETAIL_schedule_type_fragment";

    // 出发城市
    @BindView(R.id.start_city_textview)
    TextView mStartCityTextView;
    // 出行时间
    @BindView(R.id.trip_time_textview)
    TextView mTripTimeTextView;
    // 出行日期
    @BindView(R.id.trip_date_textview)
    TextView mTripDateTextView;
    // 到达城市
    @BindView(R.id.arrival_city_textview)
    TextView mArrivalCityTextView;

    // 车型
    @BindView(R.id.bus_type_textview)
    TextView mBusTypeTextView;
    // 票价
    @BindView(R.id.bus_ticket_price_textview)
    TextView mBusTicketPriceTextView;

    // 出行乘客列表
    @BindView(R.id.added_passengers_recycler)
    RecyclerView mAddedPassengersRecycler;

    // 取票人
    @BindView(R.id.tickets_taker_info_operation_bar)
    RelativeLayout mTicketsTakerInfoOperationBar;
    // 取票人信息布局
    @BindView(R.id.tickets_taker_info)
    LinearLayout mTicketsTakerInfoLayout;
    // 取票人姓名
    @BindView(R.id.tickets_taker_name_textview)
    TextView mTakerNameTextView;
    // 取票人手机号
    @BindView(R.id.tickets_taker_mobile_textview)
    TextView mTakerMobileTextView;
    // 取票人身份证号
    @BindView(R.id.tickets_taker_id_number_textview)
    TextView mTakerIdNumberTextView;

    // 总价:￥99.00
    @BindView(R.id.total_amount_textview)
    TextView mTotalAmountTextView;
    // 乘客人数:(5人)
    @BindView(R.id.passengers_number_textview)
    TextView mPsgersNumberTextView;

    //底栏箭头
    @BindView(R.id.iv_icon_up_arrow)
    ImageView mUpArrowIv;
    // 确认按钮
    @BindView(R.id.order_confirm_textview)
    TextView mOrderConfirmTextView;

    //案底幕布
    @BindView(R.id.frame_zoume_bus_screen)
    FrameLayout mTicketScreenFrame;

    //优惠券
    @BindView(R.id.tv_bus_coupon_state)
    TextView mTvBusCouponState;
    @BindView(R.id.iv_bus_coupon_arrow)
    ImageView mIvBusCouponArrow;
    @BindView(R.id.rl_bus_coupon_bar)
    RelativeLayout mRlBusCouponBar;

    //不区分儿童成人
    @BindView(R.id.tv_zoume_bus_pop_totle_price)
    TextView mTvZoumeBusPopTotlePrice;
    @BindView(R.id.tv_zoume_bus_pop_totle_coupon)
    TextView mTvZoumeBusPopTotleCoupon;
    @BindView(R.id.ll_zoume_bus_popup_container)
    LinearLayout mLlZoumeBusPopupContainer;
    //儿童成人分开
    @BindView(R.id.tv_zoume_bus_pop_adult_price)
    TextView mTvZoumeBusPopAdultPrice;
    @BindView(R.id.tv_zoume_bus_pop_children_price)
    TextView mTvZoumeBusPopChildrenPrice;
    @BindView(R.id.tv_zoume_bus_pop_totle_coupon_ischild)
    TextView mTvZoumeBusPopTotleCouponIschild;
    @BindView(R.id.ll_zoume_bus_popup_container_ischild)
    LinearLayout mLlZoumeBusPopupContainerIschild;

    // Recycler适配器
    SelectPsgersAdapter mSelectPsgersAdapter;

    // Injector
    BusServiceComponent component;

    @Inject
    BusTicketOrderPresenter mBusTicketOrderPresenter;
    @Inject
    PerfectCouponPresenter mPerfectCouponPresenter;
    // 已添加的乘客
    List<ZMPassenger> selectedPsgers = new ArrayList<ZMPassenger>();
    // 取票人
    List<ZMPassenger> ticketsTakers = new ArrayList<ZMPassenger>();
    // 总价
    double totalPriceWhenChildHalfPrice;
    // Dialogs
    MaterialDialog dialogForWaitingDetail = null;
    MaterialDialog dialogForWaitingOrderConfirm = null;
    //查询总价
    double totalAmount;
    //pop高度
    int popHeight;

    // 固定时刻类巴士:儿童半价
    int childCount = 0;
    int adultCount = 0;
    boolean isHalfChild;
    LinearLayout mPopupContainerLl;


    private OneYxBusInfoRequest mOneYxBusInfoRequest;
    // 当前车次
    private OneBusEntry mCurrentBusService;
    // 票单价
    private double unitPrice;
    private String couponId;

    private CouponInfo perfectCoupon;

    private ScheduleType mScheduleType;
    private MaterialDialog mErrorMsgDialog;
    private MaterialDialog mRenderFailureDialog;

    private int orderTpye;
    /**
     * 旋转底栏箭头的起始角度
     */
    private int mFromDegree = 0;
    /**
     * 旋转底栏箭头的到达角度
     */
    private int mToDegree = 180;
    /**
     * 底栏箭头旋转和弹出框弹出标志位
     */
    private boolean needShowPopup = true;


    public static BusTicketOrderFragment newInstance(OneYxBusInfoRequest param, ScheduleType scheduleType) {
        Bundle args = new Bundle();
        args.putSerializable(KEY_TICKET_DETAIL_PARAM, param);
        args.putSerializable(KEY_TICKET_SCHEDULE_TYPE, scheduleType);
        BusTicketOrderFragment fragment = new BusTicketOrderFragment();
        fragment.setArguments(args);
        return fragment;
    }

    private void parseArguments() {
        // 获取param
        Bundle args = getArguments();
        if (null != args) {
            mOneYxBusInfoRequest = (OneYxBusInfoRequest) args.getSerializable(KEY_TICKET_DETAIL_PARAM);
            mScheduleType = (ScheduleType) args.getSerializable(KEY_TICKET_SCHEDULE_TYPE);
            porcessOrderType(mScheduleType);
        }
    }

    private void porcessOrderType(ScheduleType scheduleType) {
        switch (scheduleType) {
            case V_XD_BUS://新帝巴士
                orderTpye = 5;
                break;
            case V_DABA_BUS://大巴网接口
                orderTpye = 9;
                break;
            case V_FT_BUS: //固定(时刻)巴士
                orderTpye = 8;
                break;
            default:
                break;
        }
    }

    private void onRxBusEvent() {
        getSubscription().add(toSubscription(RenderSelectedPsgersEvent.class,
                new Action1<RenderSelectedPsgersEvent>() {
                    @Override
                    public void call(RenderSelectedPsgersEvent renderSelectedPsgersEvent) {
                        selectedPsgers.clear();
                        selectedPsgers.addAll(renderSelectedPsgersEvent.getSelectedPsgers());
                        if (null == mSelectPsgersAdapter) {
                            refreshUI(selectedPsgers);
                        } else {
                            mSelectPsgersAdapter.notifyDataSetChanged();
                        }

                        // 处理取票人信息
                        if (0 < ticketsTakers.size()) {
                            if (!selectedPsgers.contains(ticketsTakers.get(0))) {
                                hideTakerUI();
                            }
                        }

                        // 计算乘客人数、订单总价
                        calculatePsgersNumber();
                        calculateTotalAmount();
                        queryPerfectCoupon();
                        // 定时类bus不需要取票人, 选完乘客即可下单
                        if (ScheduleType.V_FT_BUS == mOneYxBusInfoRequest.getType()) {
                            // 设置确定按钮
                            mOrderConfirmTextView.setEnabled(selectedPsgers.size() > 0);
                        }
                    }
                },
                new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        LOG.e(TAG, "throwable=" + throwable.toString());
                        onRxBusEvent();
                    }
                }
        ));

        getSubscription().add(toSubscription(DeletePsgerEvent.class,
                new Action1<DeletePsgerEvent>() {
                    @Override
                    public void call(DeletePsgerEvent deletePsgerEvent) {
                        // 删除乘客
                        ZMPassenger p = deletePsgerEvent.getPassenger();
                        selectedPsgers.remove(p);
                        // 删除取票人
                        if (0 < ticketsTakers.size()) {
                            if (ticketsTakers.get(0).getPassengerId().equals(p.getPassengerId())) {
                                hideTakerUI();
                            }
                        }

                        // 计算乘客人数、订单总价
                        calculatePsgersNumber();
                        calculateTotalAmount();

                        resetPerfectCoupon();
                        processPopupShow(popHeight, isHalfChild, mPopupContainerLl);
                        queryPerfectCoupon();

                        // 定时类bus不需要取票人, 选完乘客即可下单
                        if (ScheduleType.V_FT_BUS == mOneYxBusInfoRequest.getType()) {
                            // 设置确定按钮
                            mOrderConfirmTextView.setEnabled(selectedPsgers.size() > 0);
                        }
                    }
                }
        ));


        getSubscription().add(toSubscription(RenderSelectedTakerEvent.class,
                new Action1<RenderSelectedTakerEvent>() {
                    @Override
                    public void call(RenderSelectedTakerEvent renderSelectedTakerEvent) {
                        ZMPassenger taker = renderSelectedTakerEvent.getTaker();
                        if (null != taker) {
                            if (!CollectionUtils.isEmpty(ticketsTakers)) {// 已选择取票人，先清除
                                ticketsTakers.remove(0);
                            }
                            ticketsTakers.add(taker);

                            // 取票人信息
                            mTicketsTakerInfoLayout.setVisibility(View.VISIBLE);
                            mTakerNameTextView.setText(taker.getRealName());
                            mTakerMobileTextView.setText(taker.getMobileNumber());
                            mTakerIdNumberTextView.setText(IDNoUtils.encryptIDNo(taker.getIdNumber()));

                            // 设置确定按钮
                            mOrderConfirmTextView.setEnabled(true);
                        }
                    }
                }
        ));
        //选择优惠券
        getSubscription().add(toSubscription(CouponSelectEvent.class, new Action1<CouponSelectEvent>() {
            @Override
            public void call(CouponSelectEvent couponSelectEvent) {
                couponId = couponSelectEvent.getCouponId();
                if (couponId != null) {
                    queryPerfectCoupon();
                } else {
                    //不使用优惠券
                    perfectCoupon = null;
                    notUseCoupon();
                }
            }
        }));
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        parseArguments();
        onRxBusEvent();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = super.onCreateView(inflater, container, savedInstanceState);
        // 取票人信息
        mTicketsTakerInfoLayout.setVisibility(View.GONE);
        // 配置recycler
        setupRecyclerView();

        // 固定时刻无取票人
        if (ScheduleType.V_FT_BUS == mOneYxBusInfoRequest.getType()) {
            mTicketsTakerInfoOperationBar.setVisibility(View.GONE);
        }
        // 获取车次详情
        mBusTicketOrderPresenter.attachView(this);
        mBusTicketOrderPresenter.getBusServiceDetail(mOneYxBusInfoRequest);
        mPerfectCouponPresenter.attachView(this);
        ButterKnife.bind(this, view);
        return view;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        initPopupBottom();
        mRlBusCouponBar.setClickable(false);
    }

    private void initPopupBottom() {
        ScheduleType scheduleType = mOneYxBusInfoRequest.getType();
        switch (scheduleType) {
            case V_DABA_BUS:
            case V_XD_BUS:
                processPopupShow(125, false, mLlZoumeBusPopupContainer);
                break;
            case V_FT_BUS:
            case V_DIY_BUS:
                totalAmount = totalPriceWhenChildHalfPrice;
                processPopupShow(149, true, mLlZoumeBusPopupContainerIschild);
                LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                        (ViewGroup.LayoutParams.MATCH_PARENT),
                        DensityUtils.dip2px(mActivity, 48));
                layoutParams.setMargins(0, 0, 0, 0);
                mRlBusCouponBar.setLayoutParams(layoutParams);
                break;
        }
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);
    }

    @Override
    public void onStart() {
        super.onStart();
    }

    private void refreshUI(List<ZMPassenger> psgers) {
        mSelectPsgersAdapter = new SelectPsgersAdapter(component.context(), psgers, PsgerItemType.DELETABLE, mScheduleType);
        mAddedPassengersRecycler.setAdapter(mSelectPsgersAdapter);
    }

    // 隐藏取票人信息
    private void hideTakerUI() {
        ticketsTakers.clear();
        mTicketsTakerInfoLayout.setVisibility(View.GONE);

        // 设置确定按钮
        mOrderConfirmTextView.setEnabled(false);
    }

    /**
     * 配置RecyclerView
     */
    private void setupRecyclerView() {
        mAddedPassengersRecycler.setLayoutManager(new LinearLayoutManager(component.context()));
        mAddedPassengersRecycler.setItemAnimator(new DefaultItemAnimator());
    }

    @Override
    public void onResume() {
        super.onResume();
        mBusTicketOrderPresenter.onResume();
        mPerfectCouponPresenter.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mBusTicketOrderPresenter.onPause();
        mPerfectCouponPresenter.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mBusTicketOrderPresenter.onDestroy();
        mPerfectCouponPresenter.onDestroy();
    }

    @Override
    protected void initializeInjector() {
        component = getComponent(BusServiceComponent.class);
        component.inject(this);
    }

    @Override
    protected int getLayoutResId() {
        return R.layout.fragment_bus_ticket_order;
    }

    @Override
    protected void setupToolBar() {
        if (getActivity() instanceof BusTicketOrderActivity) {
            ((BusTicketOrderActivity) getActivity()).setToolbar(
                    getString(R.string.bus_ticket_order_title),
                    getString(R.string.title_ticketing_information));
        }
    }

    @Override
    public void waitingForBusServiceDetailRequest(boolean isWaiting) {
        if (isWaiting) {
            dialogForWaitingDetail = new MaterialDialog.Builder(component.context())
                    .content(R.string.dialog_waiting_processing)
                    .progress(true, 0)
                    .canceledOnTouchOutside(false)
                    .show();
        } else {
            if (null != dialogForWaitingDetail) {
                dialogForWaitingDetail.dismiss();
            }
        }

    }

    @Override
    public void renderBusServiceDetail(OneBusEntry busService) {
        mCurrentBusService = busService;

        // 出发城市
        mStartCityTextView.setText(busService.getStartStationName());
        // 出行时间
        mTripTimeTextView.setText(busService.getGmtDepartTime());
        // 出行日期
        mTripDateTextView.setText(busService.getGmtDepartDate());
        // 到达城市
        mArrivalCityTextView.setText(busService.getEndStationName());

        // 车型
        mBusTypeTextView.setText(busService.getVehicleType());
        // 票价
        mBusTicketPriceTextView.setText("¥" + busService.getTicketPrice());

        // 票单价
        unitPrice = Double.valueOf(busService.getTicketPrice());

        processPopupShow(popHeight, isHalfChild, mPopupContainerLl);
    }


    @Override
    public void renderFixedTimeBusOrder(BizOrder order) {
        getAppComponent().navigator().navigateToPayment(component.context(), order);
    }

    @Override
    public void renderOnFailure(String errorMessage) {
        mRenderFailureDialog = new MaterialDialog.Builder(component.context())
                .title(R.string.dialog_title_hint)
                .content(errorMessage)
                .positiveText(R.string.dialog_confirm)
                .positiveColorRes(R.color.app_primary_blue)
                .canceledOnTouchOutside(false)
                .build();
        mRenderFailureDialog.show();
    }

    @Override
    public void showErrorMessage(String errorMessage) {
        if (errorMessage != null) {
            if (errorMessage.equalsIgnoreCase("timeout")) {
                errorMessage = "连接超时";
            } else {
                errorMessage = getString(R.string.net_error);
            }

            mErrorMsgDialog = new MaterialDialog.Builder(component.context())
                    .title(R.string.dialog_title_hint)
                    .content(errorMessage)
                    .positiveText(R.string.dialog_confirm)
                    .positiveColorRes(R.color.app_primary_blue)
                    .canceledOnTouchOutside(false)
                    .build();

            mErrorMsgDialog.show();
        }
    }

    @Override
    public void waitingForOrderConfirm(boolean isWaiting) {
        if (isWaiting) {
            dialogForWaitingOrderConfirm = new MaterialDialog.Builder(component.context())
                    .content(R.string.dialog_waiting_processing)
                    .progress(true, 0)
                    .canceledOnTouchOutside(false)
                    .show();
        } else {
            if (null != dialogForWaitingOrderConfirm) {
                dialogForWaitingOrderConfirm.dismiss();
            }
        }
    }

    @Override
    public void renderBusTicketOrder(ZMBusTicketOrder busTicketOrder) {
        // 传递乘车人数
        busTicketOrder.setPassengerCount(selectedPsgers.size());
        getAppComponent().navigator().navigateToPayment(component.context(), busTicketOrder);
    }

    @OnClick(R.id.add_passenger_operation_bar)
    void onAddPassengerOperationBarClick() {
        switch (mScheduleType) {
            case V_XD_BUS:
            case V_DABA_BUS:
                getAppComponent().navigator().navigateToSelectPassengers(
                        component.context(),
                        selectedPsgers,
                        PsgerItemType.MULTI_SELECT,
                        MultipleSelectType.TICKET_BUS_ORDER_MULTI_SELECT);
                break;
            case V_FT_BUS:
                getAppComponent().navigator().navigateToSelectPassengers(
                        component.context(),
                        selectedPsgers,
                        PsgerItemType.MULTI_SELECT,
                        MultipleSelectType.FIXED_BUS_ORDER_MULTI_SELECT);
                break;
        }
    }

    @OnClick(R.id.tickets_taker_info_operation_bar)
    void onTakerInfoOperationBar() {
        // 未添加乘客时，不允许选择取票人
        if (CollectionUtils.isEmpty(selectedPsgers))
            return;

        if (0 < ticketsTakers.size()) {// 当前有取票人
            ZMPassenger t = ticketsTakers.get(0);
            for (ZMPassenger p : selectedPsgers) {
                if (t.getPassengerId().equals(p.getPassengerId())) {
                    p.setSelected(true);
                } else {
                    p.setSelected(false);
                }
            }
        } else {// 当前无取票人
            for (int i = 0; i < selectedPsgers.size(); i++) {
                ZMPassenger p = selectedPsgers.get(i);
                p.setSelected(0 == i);
            }
        }

        getAppComponent().navigator().navigateToSelectPassengers(component.context(), selectedPsgers, PsgerItemType.SINGLE_SELECT);
    }

    /**
     * 确认订单:车票锁票 or 固定时刻类巴士下单
     */
    @OnClick(R.id.order_confirm_textview)
    void onOrderConfirmClick() {
        ScheduleType scheduleType = mOneYxBusInfoRequest.getType();
        LOG.e(TAG, "scheduleType=" + scheduleType);
        switch (scheduleType) {
            case V_FT_BUS:
                generateFixedTimeBusOrder();
                break;
            default:
                MaterialDialog materialDialog = new MaterialDialog.Builder(component.context())
                        .content(R.string.hint_price_fluctuation)
                        .positiveText(R.string.dialog_confirm)
                        .positiveColorRes(R.color.app_primary_blue)
                        .canceledOnTouchOutside(false)
                        .onPositive(new MaterialDialog.SingleButtonCallback() {
                            @Override
                            public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                                dialog.dismiss();
                                // 锁票
                                mBusTicketOrderPresenter.lockTickets(mCurrentBusService, selectedPsgers, ticketsTakers.get(0), perfectCoupon);
                            }
                        }).build();

                materialDialog.show();
        }
    }

    /**
     * 选择优惠券
     */
    @OnClick(R.id.rl_bus_coupon_bar)
    public void onSelectCouponClick() {
        CouponSelectModel couponSelectModel = new CouponSelectModel();
        couponSelectModel.setBizType(orderTpye)
                .setOrderTotalFee(String.valueOf(totalAmount))
                .setCouponUserRelId(couponId);
        getAppComponent().navigator().navigateToCouponSelectPage(mActivity, couponSelectModel);
    }

    /**
     * 计算订单总价
     */
    private void calculateTotalAmount() {
        // 巴士车票:儿童票按全价计算
        double totalPrice = unitPrice * selectedPsgers.size();

        // 成人、儿童
        adultCount = 0;
        childCount = 0;
        for (ZMPassenger p : selectedPsgers) {
            if (ZMPassenger.ADULT == p.getPsgerCategory()) {
                ++adultCount;
            } else {
                ++childCount;
            }
        }

        totalPriceWhenChildHalfPrice = unitPrice * 0.5 * childCount + unitPrice * adultCount;
        processPopupShow(popHeight, isHalfChild, mPopupContainerLl);

        // ￥99.00
        ScheduleType scheduleType = mCurrentBusService.getType();
        switch (scheduleType) {
            case V_DABA_BUS:
            case V_XD_BUS:
                mTotalAmountTextView.setText("¥" + String.format("%.2f", totalPrice));
                totalAmount = totalPrice;
                break;
            case V_FT_BUS:
            case V_DIY_BUS:
                mTotalAmountTextView.setText("¥" + String.format("%.2f", totalPriceWhenChildHalfPrice));
                totalAmount = totalPriceWhenChildHalfPrice;
                break;
        }

    }

    /**
     * 处理弹窗相关
     *
     * @param height
     * @param isChild
     */
    public void processPopupShow(int height, boolean isChild, LinearLayout linearLayout) {
        popHeight = height;
        this.isHalfChild = isChild;
        mPopupContainerLl = linearLayout;
        if (isHalfChild) {
            mTvZoumeBusPopChildrenPrice.setText("¥" + String.format("%.2f", unitPrice / 2) + " X" + childCount);
            mTvZoumeBusPopAdultPrice.setText("¥" + String.format("%.2f", unitPrice) + " X" + adultCount);
        } else {
            mTvZoumeBusPopTotlePrice.setText("¥" + String.format("%.2f", unitPrice) + " X" + selectedPsgers.size());
        }
    }

    /**
     * 计算乘客人数
     */
    private void calculatePsgersNumber() {
        // (5人)
        String psgersNumber = "(" + selectedPsgers.size() + "人" + ")";
        mPsgersNumberTextView.setText(psgersNumber);
    }


    /**
     * 确认订单: 固定时刻类巴士
     */
    private void generateFixedTimeBusOrder() {
        // 出行乘客
        List<Contract> allPsgers = new ArrayList<>();
        for (ZMPassenger p : selectedPsgers) {
            Contract c = Contract.newBuilder()
                    .setContractType(p.getPsgerCategory() == ZMPassenger.ADULT ? ContractType.ADULT : ContractType.CHILDREN)
                    .setId(Long.valueOf(p.getPassengerId()))
                    .setIdType(p.getIdType() == 0 ? IdType.IT_DEFAULT : IdType.IDCARD)
                    .setIdNumber(p.getIdNumber())
                    .setRealname(p.getRealName())
                    .setMobile(p.getMobileNumber())
                    .setGender(p.getGender() == 0 ? GenderType.GT_DEFAULT : (p.getGender() == 1 ? GenderType.MALE : GenderType.FEMALE))
                    .build();
            allPsgers.add(c);
        }

        long userCouponId = 0;
        double discountFee = 0;
        double orderTotalFee = totalAmount;

        if (null != perfectCoupon) {
            userCouponId = perfectCoupon.getUserCouponId();
            discountFee = perfectCoupon.getDiscountFee();
            orderTotalFee = perfectCoupon.getTotalFee();
        }
        BizOrderRequest.Builder rb = BizOrderRequest.newBuilder()
                .setSrc(OrderSrcType.APP)
                .setBizType(OrderBizType.OBT_FT_BUS)
                .setScheduleId(Long.valueOf(mCurrentBusService.getScheduleNo()))
                .setTotalFee(orderTotalFee)
                .setDepartTime(mCurrentBusService.getGmtDepartDate() + " " + mCurrentBusService.getGmtDepartTime())
                .setStartStation(mCurrentBusService.getStartStationCode())
                .setEndStation(mCurrentBusService.getEndStationCode())
                .setDiscountFee(discountFee)
                .setCouponUserRelId(userCouponId)
                .setNeedFerry(false)
                .addAllContracts(allPsgers);

        mBusTicketOrderPresenter.generateOrder(rb);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (mRenderFailureDialog != null && mRenderFailureDialog.isShowing()) {
            mRenderFailureDialog.dismiss();
        }
        if (mErrorMsgDialog != null && mErrorMsgDialog.isShowing()) {
            mErrorMsgDialog.dismiss();
        }
    }

    @OnClick(R.id.rl_include_total_fee_container)
    public void onClick() {
        bindBottomPopupData(selectedPsgers);
        startArrowRotationAnimator();
    }

    /**
     * 填充弹出框数据
     */
    private void bindBottomPopupData(List<ZMPassenger> zmPassengerList) {

    }

    /**
     * 开启箭头旋转动画
     */
    private void startArrowRotationAnimator() {
        ValueAnimator passengerArrowAnimator = ObjectAnimator.ofFloat(mUpArrowIv, "rotation", mFromDegree, mToDegree);
        passengerArrowAnimator.setDuration(300);
        passengerArrowAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
                if (needShowPopup) {
                    mFromDegree = 180;
                    mToDegree = 360;
                } else {
                    mFromDegree = 0;
                    mToDegree = 180;
                }
                startPopupAnimator(needShowPopup);
                needShowPopup = !needShowPopup;
            }
        });
        passengerArrowAnimator.start();
    }

    @OnClick(R.id.frame_zoume_bus_screen)
    public void onPopupOutsideScreenClick(View view) {
        if (!needShowPopup) {
            startArrowRotationAnimator();
        }
    }

    /**
     * 启动/退出底栏弹出框
     *
     * @param needUpTranslation true,需要向上弹出,false,需要向下退出弹框
     */
    private void startPopupAnimator(boolean needUpTranslation) {
        float height = DensityUtils.dip2px(mActivity, popHeight);

        PropertyValuesHolder translationValuesHolder;
        PropertyValuesHolder alphaValuesHolder;
        ObjectAnimator translationAnimator;
        //上移
        if (needUpTranslation) {
            translationValuesHolder = PropertyValuesHolder.ofFloat("translationY", 0, (-1) * height);
            alphaValuesHolder = PropertyValuesHolder.ofFloat("alpha", 0f, 1f);
            translationAnimator = ObjectAnimator.ofPropertyValuesHolder(
                    mPopupContainerLl,
                    translationValuesHolder,
                    alphaValuesHolder
            );
            translationAnimator.setInterpolator(new DecelerateInterpolator());
            mTicketScreenFrame.setVisibility(View.VISIBLE);
        }
        //下移
        else {
            translationValuesHolder = PropertyValuesHolder.ofFloat("translationY", (-1) * height, 0);
            alphaValuesHolder = PropertyValuesHolder.ofFloat("alpha", 1f, 0f);
            translationAnimator =
                    ObjectAnimator.ofPropertyValuesHolder(
                            mPopupContainerLl,
                            translationValuesHolder,
                            alphaValuesHolder
                    );
            translationAnimator.setInterpolator(new AccelerateInterpolator());
            mTicketScreenFrame.setVisibility(View.GONE);
        }

        translationAnimator.setDuration(300);
        translationAnimator.start();
    }

    /**
     * 查询最佳
     */
    private void queryPerfectCoupon() {
        if (selectedPsgers.size() == 0) {
            mRlBusCouponBar.setClickable(false);
            mIvBusCouponArrow.setVisibility(View.INVISIBLE);
            return;
        }
        showWaitingDialog(true);
        mPerfectCouponPresenter.queryPerfectCoupon(orderTpye, totalAmount, couponId);

    }
    /**
     * 不使用优惠券
     */
    public void notUseCoupon() {
        mIvBusCouponArrow.setVisibility(View.VISIBLE);
        mTvBusCouponState.setSelected(false);
        mTvBusCouponState.setText("不使用优惠券");
        mTvZoumeBusPopTotleCoupon.setText("不使用优惠券");
        mTotalAmountTextView.setText("¥" + String.format("%.2f", totalAmount));

    }
    /**
     * 优惠券价格复位
     */
    private void resetPerfectCoupon() {
        mTvBusCouponState.setSelected(false);
        mTvBusCouponState.setText(null);
        mTvZoumeBusPopTotleCouponIschild.setText(null);
        mTvZoumeBusPopTotleCoupon.setText(null);
        mTotalAmountTextView.setText("¥" + String.format("%.2f", totalAmount));
    }

    @Override
    public void renderPerfectCouponSuccess(CouponInfo perfectCoupon) {
        String content = "";
        if (null != perfectCoupon.getCouponName()) {
            this.perfectCoupon = perfectCoupon;
            mTvBusCouponState.setSelected(true);
            content = perfectCoupon.getCouponName() + "   -¥" + (perfectCoupon.getDiscountFee());
            mTvZoumeBusPopTotleCoupon.setText("-¥" + perfectCoupon.getDiscountFee());
            mTvZoumeBusPopTotleCouponIschild.setText("-¥" + perfectCoupon.getDiscountFee());
            mTvBusCouponState.setText(content);
            mTotalAmountTextView.setText("¥" + String.format("%.2f", perfectCoupon.getTotalFee()));
            couponId = String.valueOf(perfectCoupon.getUserCouponId());
            mRlBusCouponBar.setClickable(true);
            mIvBusCouponArrow.setVisibility(View.VISIBLE);
        } else {
            mRlBusCouponBar.setClickable(false);
            mIvBusCouponArrow.setVisibility(View.INVISIBLE);
        }


        showWaitingDialog(false);
    }

    @Override
    public void renderPerfectCouponFailure() {
        showWaitingDialog(false);
    }

    public void showWaitingDialog(boolean isWaiting) {
        if (isWaiting) {
            dialogForWaitingDetail = new MaterialDialog.Builder(component.context())
                    .content(R.string.dialog_waiting_processing)
                    .progress(true, 0)
                    .canceledOnTouchOutside(false)
                    .show();
        } else {
            if (null != dialogForWaitingDetail) {
                dialogForWaitingDetail.dismiss();
            }
        }

    }
}
